home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / inmemory / temptbl.pas < prev    next >
Pascal/Delphi Source File  |  1995-12-22  |  6KB  |  189 lines

  1. {
  2.  
  3.  This is an TempTable example. Free for anyone to use, modify and do
  4.  whatever else you wish.
  5.  
  6.  TempTables are supposedly also in-memory tables and provide all of the
  7.  functionality of regular tables. The problem with these is that in DB.PAS
  8.  there is a line in TDataSet.InternalOpen that sets CanModify to False if
  9.  the table is temporary. Why - I don't know, but if you have the VCL source
  10.  (which I highly recommend if you're serious about Delphi programming) then
  11.  you can just comment that part out. Otherwise - this unit is useless to you :(
  12.  
  13.  Just like all things free it comes with no guarantees. I cannot be responsible
  14.  for any damage this code may cause.
  15.  
  16.  Thanks to Steve Garland <72700.2407@compuserve.com> for his help. He
  17.  created his own variation of an in-memory table component and I used it
  18.  to get started.
  19.  
  20.  If you have comments - please contact me at INTERNET:grisha@mira.com
  21.  
  22.  Happy hacking!
  23.  
  24.  Gregory Trubetskoy
  25.  
  26. }
  27.  
  28. unit Temptbl;
  29.  
  30. interface
  31.  
  32. uses DBTables, WinTypes, WinProcs, DBITypes, DBIProcs, DB, SysUtils;
  33.  
  34.  
  35. type TTempTable = class(TTable)
  36.   private
  37.     hCursor: hDBICur;
  38.     procedure EncodeFieldDesc(var FieldDesc: FLDDesc;
  39.       const Name: string; DataType: TFieldType; Size: Word);
  40.     function CreateHandle: HDBICur; override;
  41.     procedure EncodeIndexDesc(var IndexDesc: IDXDesc;
  42.       const Name, Fields: string; Options: TIndexOptions);
  43.   public
  44.     procedure CreateTable;
  45.   end;
  46.  
  47. implementation
  48.  
  49. function TTempTable.CreateHandle;
  50. begin
  51.   Result := hCursor;
  52. end;
  53.  
  54. procedure TTempTable.EncodeIndexDesc(var IndexDesc: IDXDesc;
  55.   const Name, Fields: string; Options: TIndexOptions);
  56. var
  57.   Pos: Integer;
  58. begin
  59.   FillChar(IndexDesc, SizeOf(IndexDesc), 0);
  60.   with IndexDesc do
  61.   begin
  62.   {  if IsDBaseTable then
  63.       AnsiToNative(DBLocale, Name, szTagName, SizeOf(szTagName) - 1)
  64.     else
  65.       AnsiToNative(DBLocale, Name, szName, SizeOf(szName) - 1);   }
  66.     bPrimary := ixPrimary in Options;
  67.     bUnique := ixUnique in Options;
  68.     bDescending := ixDescending in Options;
  69.     bMaintained := True;
  70.     bCaseInsensitive := ixCaseInsensitive in Options;
  71.     if ixExpression in Options then
  72.     begin
  73.       bExpIdx := True;
  74.       AnsiToNative(DBLocale, Fields, szKeyExp, SizeOf(szKeyExp) - 1);
  75.     end else
  76.     begin
  77.       Pos := 1;
  78.       while (Pos <= Length(Fields)) and (iFldsInKey < 16) do
  79.       begin
  80.         aiKeyFld[iFldsInKey] :=
  81.           FieldDefs.Find(ExtractFieldName(Fields, Pos)).FieldNo;
  82.         Inc(iFldsInKey);
  83.       end;
  84.     end;
  85.   end;
  86. end;
  87.  
  88.  
  89. procedure TTempTable.EncodeFieldDesc(var FieldDesc: FLDDesc;
  90.   const Name: string; DataType: TFieldType; Size: Word);
  91. const
  92.   TypeMap: array[TFieldType] of Byte = (
  93.     fldUNKNOWN, fldZSTRING, fldINT16, fldINT32, fldUINT16, fldBOOL,
  94.     fldFLOAT, fldFLOAT, fldBCD, fldDATE, fldTIME, fldTIMESTAMP, fldBYTES,
  95.     fldVARBYTES, fldBLOB, fldBLOB, fldBLOB);
  96. begin
  97.   with FieldDesc do
  98.   begin
  99.     AnsiToNative(Locale, Name, szName, SizeOf(szName) - 1);
  100.     iFldType := TypeMap[DataType];
  101.     case DataType of
  102.       ftString, ftBytes, ftVarBytes, ftBlob, ftMemo, ftGraphic:
  103.         iUnits1 := Size;
  104.       ftBCD:
  105.         begin
  106.           iUnits1 := 32;
  107.           iUnits2 := Size;
  108.         end;
  109.     end;
  110.     case DataType of
  111.       ftCurrency:
  112.         iSubType := fldstMONEY;
  113.       ftBlob:
  114.         iSubType := fldstBINARY;
  115.       ftMemo:
  116.         iSubType := fldstMEMO;
  117.       ftGraphic:
  118.         iSubType := fldstGRAPHIC;
  119.     end;
  120.   end;
  121. end;
  122.  
  123. procedure TTempTable.CreateTable;
  124. var
  125.   I, J: Integer;
  126.   FieldDescs: PFLDDesc;
  127.   ValCheckPtr: PVCHKDesc;
  128.   DriverTypeName: DBINAME;
  129.   TableDesc: CRTblDesc;
  130. begin
  131.   CheckInactive;
  132.   if FieldDefs.Count = 0 then
  133.     for I := 0 to FieldCount - 1 do
  134.       with Fields[I] do
  135.         if not Calculated then
  136.           FieldDefs.Add(FieldName, DataType, Size, Required);
  137.   FieldDescs := nil;
  138.   FillChar(TableDesc, SizeOf(TableDesc), 0);
  139.   with TableDesc do
  140.   begin
  141.     SetDBFlag(dbfTable, True);
  142.     try
  143.       AnsiToNative(Locale, TableName, szTblName, SizeOf(szTblName) - 1);
  144.       {if GetTableTypeName <> nil then
  145.         StrCopy(szTblType, GetTableTypeName);}
  146.       iFldCount := FieldDefs.Count;
  147.       FieldDescs := AllocMem(iFldCount * SizeOf(FLDDesc));
  148.       for I := 0 to FieldDefs.Count - 1 do
  149.         with FieldDefs[I] do
  150.         begin
  151.           EncodeFieldDesc(PFieldDescList(FieldDescs)^[I], Name,
  152.             DataType, Size);
  153.           if Required then Inc(iValChkCount);
  154.         end;
  155.       pFldDesc := AllocMem(iFldCount * SizeOf(FLDDesc));
  156.       Check(DbiTranslateRecordStructure(nil, iFldCount, FieldDescs,
  157.         nil, nil, pFLDDesc));
  158.       iIdxCount := IndexDefs.Count;
  159.       pIdxDesc := AllocMem(iIdxCount * SizeOf(IDXDesc));
  160.       for I := 0 to IndexDefs.Count - 1 do
  161.         with IndexDefs[I] do
  162.           EncodeIndexDesc(PIndexDescList(pIdxDesc)^[I], Name, Fields,
  163.             Options);
  164.       if iValChkCount <> 0 then
  165.       begin
  166.         pVChkDesc := AllocMem(iValChkCount * SizeOf(VCHKDesc));
  167.         ValCheckPtr := pVChkDesc;
  168.         for I := 0 to FieldDefs.Count - 1 do
  169.           if FieldDefs[I].Required then
  170.           begin
  171.             ValCheckPtr^.iFldNum := I + 1;
  172.             ValCheckPtr^.bRequired := True;
  173.             Inc(ValCheckPtr);
  174.           end;
  175.       end;
  176.       Check(DbiCreateTempTable(DBHandle, TableDesc, hCursor));
  177.       Check(DbiSetProp(hDBIObj(hCursor), curXLTMODE, LongInt(xltFIELD)));
  178.     finally
  179.       if pVChkDesc <> nil then FreeMem(pVChkDesc, iValChkCount * SizeOf(VCHKDesc));
  180.       if pIdxDesc <> nil then FreeMem(pIdxDesc, iIdxCount * SizeOf(IDXDesc));
  181.       if pFldDesc <> nil then FreeMem(pFldDesc, iFldCount * SizeOf(FLDDesc));
  182.       if FieldDescs <> nil then FreeMem(FieldDescs, iFldCount * SizeOf(FLDDesc));
  183.       SetDBFlag(dbfTable, False);
  184.     end;
  185.   end;
  186. end;
  187.  
  188. end.
  189.